;(function($)  {

    function Upload() {}

    Upload.prototype.init = function (options) {
        setting = $.extend({
            name: 'image',
            type: 'image',
            uploadEle: null,
            uploadUrl: null,
            uploadCheckUrl: null,
            defaultImage: '/images/image.png',
            mimeTypes: [],
            maxSize: 10485760,
            uploadPath: 'default',
            uploadError: null,
            multiple: 1,
            afterSelected: function(file,Upload){
                Upload.setting.uploadEle.next('img,video').attr('src',URL.createObjectURL(file)).attr('poster','');
                return true;
            },
            uploadSuccess: function(res,Upload){
                var setting = Upload.setting;
                if(setting.multiple > 1){
                    var showFileHtml;
                    switch (setting.type) {
                        case 'video':
                            showFileHtml = '<video class="file-responsive" controls="controls" src="'+res.data.fileUrl+'"></video>';
                            break;
                        case 'voice' :
                            showFileHtml = '<audio class="file-responsive" controls><source src="'+res.data.fileUrl+'"></audio>';
                            break;
                        default:
                            showFileHtml = '<img class="file-responsive" src="'+res.data.fileUrl+'">';
                            break;
                    }
                    setting.uploadEle.before('<div class="file-div-box sortable">' +
                        '<input type="hidden" name="'+setting.name+'[]" value="'+res.data.fileUrl+'">' +
                        '<div class="file-delete"><i class="fa fa-trash-o" title="删除"></i></div>' +
                        showFileHtml +
                        '</div>');
                    if(setting.multiple === $('.file-list-box .file-div-box.sortable').length){
                        $(setting.uploadEle).hide();
                    }
                }else{
                    setting.fileBoxEle.find('input[type=hidden]').val(res.data.fileUrl)
                }
            }
        }, options);

        setting.fileBoxEle = $(setting.uploadEle).closest('.file-list-box');
        setting.inputHideEle = null;

        if(setting.multiple>1){
            var fileListBox = $('.file-list-box');
            if(fileListBox.length){
                new Sortable(fileListBox[0], {
                    swap: true,
                    draggable: '.sortable',
                    animation: 150
                });
            }
        }else{
            setting.inputHideEle = setting.fileBoxEle.find('input[type=hidden]');
        }

        this.setting = setting;

        return this;
    };

    Upload.prototype.click = function(){
        var _self = this;

        $(document).on('click',this.setting.uploadEle,function () {

            var uploadInput = $('<input type="file" style="display: none;" '+(_self.setting.multiple>1?'multiple':'')+' accept="'+_self.setting.mimeTypes.toString()+'" />');

            uploadInput.change(function(e){

                var files = e.target.files;

                $.each(files,function (index){
                    var file = files[index];

                    file.extension = file.name.indexOf('.') > -1 ? file.name.split('.').pop() : 'tmp';

                    if(!_self.beforeRequest(file)) return true;

                    var options = _self.afterSelected(file);

                    if(options === false) return true;

                    var params = {};
                    if(typeof options === 'object'){
                        params = options;
                    }
                    params.uploadPath = _self.setting.uploadPath;

                    _self.md5(file).then(function (fileMd5){
                        params.fileMd5 = fileMd5;
                    }).finally(function (){
                        _self.request(file,params);
                    });
                });
            });
            uploadInput.val('').click();
            _self.setting.uploadEle = $(this);
        });

        this.setting.fileBoxEle.on('click','.file-delete',function (){
            if(_self.setting.multiple > 1){
                $(this).closest('.file-div-box').remove();
                if($('.file-list-box .file-div-box.sortable').length < _self.setting.multiple){
                    $(_self.setting.uploadEle).show();
                }
            }else{
                _self.setting.inputHideEle.val('');
                $(this).closest('.file-div-box').find('img,video').attr({poster: _self.setting.defaultImage,src:_self.setting.defaultImage});
            }
        });

        return this;
    };

    Upload.prototype.afterSelected = function(file){
        if(typeof this.setting.afterSelected === "function"){
            return this.setting.afterSelected(file,this)
        }
        return true;
    };

    Upload.prototype.beforeRequest = function(file){
        if(this.setting.mimeTypes.length && $.inArray(file.type.toLowerCase(),this.setting.mimeTypes) < 0) {
            layer.msg('上传文件上传格式错误.');
            return false;
        }

        if(this.setting.maxSize && file.size > this.setting.maxSize) {
            var showErrorSize = this.setting.maxSize/1024/1024;
            if(showErrorSize<1){
                showErrorSize = this.setting.maxSize/1024+'kb.';
            }else{
                showErrorSize += 'M.';
            }
            layer.msg('上传文件不能大于'+showErrorSize);
            return false;
        }
        return true;
    };

    Upload.prototype.request = function(file,params){
        var _self = this;

        var uploadForm = new FormData();
        if(typeof params === 'object'){
            for(var key  in params){
                uploadForm.append(key,params[key]);
            }
        }

        var doUpload = function (){
            uploadForm.append("file",file);
            $.ajax({
                type: "POST",
                url :  _self.setting.uploadUrl,
                data: uploadForm,
                async: false,
                cache: false,
                contentType: false,
                processData: false,
                success: function (res) {
                    layer.msg(res.message);
                    if(typeof _self.setting.uploadSuccess === "function"){
                        _self.setting.uploadSuccess(res,_self);
                    }
                },
                error: function (jqXHR) {
                    layer.msg("上传文件失败");
                    if(typeof _self.setting.ploadError === "function"){
                        _self.setting.uploadError(jqXHR,_self);
                    }
                }
            });
        }

        if( _self.setting.uploadCheckUrl && params.fileMd5.length){
            params.fileName = params.fileMd5+'.'+file.extension
            $.post(_self.setting.uploadCheckUrl,params,function (res){
                if(res.code){
                    _self.setting.uploadSuccess(res,_self);
                }else{
                    doUpload();
                }
            });
        }else{
            doUpload();
        }

    };

    Upload.prototype.md5 = function(file){
        return new Promise(function(resolve, reject) {
            var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
            var chunkSize = 1024;
            var chunks = Math.ceil(file.size / chunkSize);
            var currentChunk = 0;
            var spark = new SparkMD5.ArrayBuffer();
            var fileReader = new FileReader();
            fileReader.onload = function(e) {
                spark.append(e.target.result);
                currentChunk++;
                if (currentChunk < chunks) {
                    loadNext();
                } else {
                    resolve(spark.end());
                }
            };
            fileReader.onerror = function(e) {
                reject(e);
            };
            function loadNext() {
                var start = currentChunk * chunkSize;
                var end = start + chunkSize;
                if (end > file.size){
                    end = file.size;
                }
                fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
            }
            loadNext();
        });
    };

    window.Upload = Upload;

})(jQuery);